package cn.fufeiii.bt.statemachine;

import com.alibaba.cola.statemachine.Action;
import com.alibaba.cola.statemachine.Condition;
import com.alibaba.cola.statemachine.StateMachine;
import com.alibaba.cola.statemachine.builder.StateMachineBuilder;
import com.alibaba.cola.statemachine.builder.StateMachineBuilderFactory;
import lombok.Data;

/**
 * 参考 : <a href="https://github.com/alibaba/COLA/tree/master/cola-components/cola-component-statemachine">...</a>
 *
 * @author FuFei
 */
public class StateMachineConfig {

    public StateMachine<State, Event, Context> stateMachine() {
        StateMachineBuilder<State, Event, Context> builder = StateMachineBuilderFactory.create();

        // 初始化 -> 待支付
        builder.externalTransition().from(State.INITIALIZATION).to(State.PAYMENT_WAIT).on(Event.REQUEST_PRE_PAYMENT)
                .when(this.checkCondition()).perform(this.executeAction());
        // 待支付 -> 支付成功
        builder.externalTransition().from(State.PAYMENT_WAIT).to(State.PAYMENT_SUCCESS).on(Event.RECEIVE_ACQUIRER_SUCCESS)
                .when(this.checkCondition()).perform(this.executeAction());
        // 待支付 -> 支付失败
        builder.externalTransition().from(State.PAYMENT_WAIT).to(State.PAYMENT_FAILURE).on(Event.RECEIVE_ACQUIRER_FAILURE)
                .when(this.checkCondition()).perform(this.executeAction());
        // 待支付 -> 支付关闭(主动关闭)
        builder.externalTransition().from(State.PAYMENT_WAIT).to(State.PAYMENT_CLOSE).on(Event.REQUEST_PAYMENT_CLOSE)
                .when(this.checkCondition()).perform(this.executeAction());
        // 待支付 -> 支付关闭(超时关闭)
        builder.externalTransition().from(State.PAYMENT_WAIT).to(State.PAYMENT_CLOSE).on(Event.DETECTED_PAYMENT_TIMEOUT)
                .when(this.checkCondition()).perform(this.executeAction());

        StateMachine<State, Event, Context> stateMachine = builder.build("stm");
        stateMachine.showStateMachine();
        return stateMachine;
    }

    public Condition<Context> checkCondition() {
        return new Condition<Context>() {
            @Override
            public boolean isSatisfied(Context context) {
                return false;
            }
        };
    }

    public Action<State, Event, Context> executeAction() {
        return new Action<State, Event, Context>() {
            @Override
            public void execute(State from, State to, Event event, Context context) {
            }
        };
    }

    enum State {
        INITIALIZATION, PAYMENT_WAIT, PAYMENT_SUCCESS, PAYMENT_FAILURE, PAYMENT_CLOSE,
    }

    enum Event {
        REQUEST_PRE_PAYMENT, RECEIVE_ACQUIRER_SUCCESS, RECEIVE_ACQUIRER_FAILURE, REQUEST_PAYMENT_CLOSE, DETECTED_PAYMENT_TIMEOUT
    }

    @Data
    static class Context {
        // 领域实体信息
        private Object domain;
        // 其他信息
        private Object other;
    }

}
